package org.elsfs.cloud.common.mybatis.ext.sql;


import org.elsfs.cloud.common.mybatis.ext.sql.support.limit.LimitItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.limit.StandardLimitItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.order.AscOrderItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.order.DescOrderItem;
import org.elsfs.cloud.common.mybatis.ext.sql.support.order.OrderItem;

import java.util.Arrays;
import java.util.Collection;

/**
 * 抽象可排序条件实现
 *
 * @param <C> 子类具体类型
 */
public abstract class AbstractSortableCondition<C extends AbstractSortableCondition<C>> extends AbstractCondition<C> implements SortableCondition<C> {

    /**
     * 升序排序
     *
     * @param fields 排序字段
     * @return 具体实现
     */
    @Override
    public C orderByAsc(String... fields) {
        for (String field : fields) {
            this.addOrderItem(
                new AscOrderItem(field)
            );
        }

        return this.childThis;
    }

    /**
     * 升序排序
     *
     * @param fields 排序字段枚举
     * @return 具体实现
     */
    @Override
    public C orderByAsc(Enum<?>... fields) {
        return this.orderByAsc(
            Arrays.stream(fields)
                .map(this::resolveFieldName)
                .toList()
        );
    }

    /**
     * 升序排序
     *
     * @param fields 排序字段
     * @return 具体实现
     */
    @Override
    public C orderByAsc(Collection<String> fields) {
        for (String field : fields) {
            this.addOrderItem(
                new AscOrderItem(field)
            );
        }

        return this.childThis;
    }

    /**
     * 升序排序
     *
     * @param fields 排序字段枚举
     * @return 具体实现
     */
    @Override
    public C orderByEnumAsc(Collection<Enum<?>> fields) {
        return this.orderByAsc(
            fields.stream()
                .map(this::resolveFieldName)
                .toList()
        );
    }

    /**
     * 降序排序
     *
     * @param fields 排序字段
     * @return 具体实现
     */
    @Override
    public C orderByDesc(String... fields) {
        for (String field : fields) {
            this.addOrderItem(
                new DescOrderItem(field)
            );
        }

        return this.childThis;
    }

    /**
     * 降序排序
     *
     * @param fields 排序字段枚举
     * @return 具体实现
     */
    @Override
    public C orderByDesc(Enum<?>... fields) {
        return this.orderByDesc(
            Arrays.stream(fields)
                .map(this::resolveFieldName)
                .toList()
        );
    }

    /**
     * 降序排序
     *
     * @param fields 排序字段
     * @return 具体实现
     */
    @Override
    public C orderByDesc(Collection<String> fields) {
        for (String field : fields) {
            this.addOrderItem(
                new DescOrderItem(field)
            );
        }

        return this.childThis;
    }

    /**
     * 降序排序
     *
     * @param fields 排序字段枚举
     * @return 具体实现
     */
    @Override
    public C orderByEnumDesc(Collection<Enum<?>> fields) {
        return this.orderByDesc(
            fields.stream()
                .map(this::resolveFieldName)
                .toList()
        );
    }

    /**
     * 排序
     *
     * @param isAsc  是否升序
     * @param fields 排序字段
     * @return 具体实现
     */
    @Override
    public C orderBy(boolean isAsc, String... fields) {
        if (isAsc) {
            return this.orderByAsc(fields);
        }

        return this.orderByDesc(fields);
    }

    /**
     * 排序
     *
     * @param isAsc  是否升序
     * @param fields 排序字段枚举
     * @return 具体实现
     */
    @Override
    public C orderBy(boolean isAsc, Enum<?>... fields) {
        return this.orderBy(
            isAsc,
            Arrays.stream(fields)
                .map(this::resolveFieldName)
                .toList()
        );
    }

    /**
     * 排序
     *
     * @param isAsc  是否升序
     * @param fields 排序字段
     * @return 具体实现
     */
    @Override
    public C orderBy(boolean isAsc, Collection<String> fields) {
        if (isAsc) {
            return this.orderByAsc(fields);
        }

        return this.orderByDesc(fields);
    }

    /**
     * 排序
     *
     * @param isAsc  是否升序
     * @param fields 排序字段枚举
     * @return 具体实现
     */
    @Override
    public C orderByEnum(boolean isAsc, Collection<Enum<?>> fields) {
        return this.orderBy(
            isAsc,
            fields.stream()
                .map(this::resolveFieldName)
                .toList()
        );
    }

    /**
     * 限制数量
     *
     * @param number 数量
     * @return 具体实现
     */
    @Override
    public C limit(long number) {
        this.setLimitItem(
            new StandardLimitItem(number)
        );

        return this.childThis;
    }

    /**
     * 添加排序项
     *
     * @param orderItem 排序项
     */
    protected abstract void addOrderItem(OrderItem orderItem);

    /**
     * 设置限制数量项
     *
     * @param limitItem 限制数量项
     */
    protected abstract void setLimitItem(LimitItem limitItem);
}
